From : C.Dimitrakakis (MBGE4CD1@fs1.ee.man.ac.uk)
Subject : Reducing colors of a shape, with dithering.
Ok, this is the extendend version with dithering!
Rate and r2 are the rates of proportionality of
dither colour usage. (How much % will be used for each colour)
Anyway, this is *not* the correct rate. It is just an estimate.
For a correct rate
if the dithering pair is represented by the points A,B in space
and point T represents the original color,
then find point C where AB and TC intersect, with TC being
perpendicular to AB, thus finding the ratio AC/BC
Altough that above gives you always the correct ratio,
this one is almost as good. (but not always),
but is a lot,lot faster.
So, take a look:
*************************
SCREEN 11
sources = 4
targets = 8
depth = 16
RANDOMIZE TIMER
DIM r(sources), g(sources), b(sources)
DIM red(targets), green(targets), blue(targets)
DIM rd(targets), gd(targets), bd(targets)
'Setting up Initial colours
FOR n = 1 TO sources
r(n) = INT(RND * depth)
g(n) = INT(RND * depth)
b(n) = INT(RND * depth)
PRINT r(n), g(n), b(n)
NEXT n
PRINT "-------------------------------------"
'setting target colours
FOR n = 1 TO targets
red(n) = INT(RND * depth)
green(n) = INT(RND * depth)
blue(n) = INT(RND * depth)
PRINT red(n), green(n), blue(n)
NEXT n
'remap colours
FOR m = 1 TO sources
PRINT "Source", r(m), g(m), b(m)
dd = -1
sel = -1
FOR n = 1 TO targets
dr = red(n) - r(m)
dg = green(n) - g(m)
db = blue(n) - b(m)
d = SQR(dr ^ 2 + dg ^ 2 + db ^ 2)
'PRINT red(n), green(n), blue(n), d
IF dd <> -1 THEN 'if there has been a previous selection
IF d < dd THEN 'compare selections
dd = d 'select new color if
sel = n 'new target closer to source color
END IF
ELSE 'if there was no previous selection
dd = d 'select new color
sel = n
END IF
NEXT n
'show selected color
PRINT "Target", red(sel), green(sel), blue(sel), dd
'create table for possible dithers
FOR n = 1 TO targets
rd(n) = (red(sel) + red(n)) / 2
gd(n) = (green(sel) + green(n)) / 2
bd(n) = (blue(sel) + blue(n)) / 2
NEXT n
'find best dithering pair
dd2 = -1
sel2 = -1
FOR n = 1 TO targets
dr = rd(n) - r(m)
dg = gd(n) - g(m)
db = bd(n) - b(m)
d = SQR(dr ^ 2 + dg ^ 2 + db ^ 2)
' PRINT rd(n), gd(n), bd(n), d
IF dd2 <> -1 THEN 'if there has been a previous selection
IF d < dd2 THEN 'compare selections
dd2 = d 'select new color if
sel2 = n 'new target closer to source color
END IF
ELSE 'if there was no previous selection
dd2 = d 'select new color
sel2 = n
END IF
NEXT n
PRINT "Target2", red(sel2), green(sel2), blue(sel2)
PRINT "Average", rd(sel2), gd(sel2), bd(sel2), dd2
'Now, take a look at the distances
'to find the rate of proportionality
rate = dd2 / dd
PRINT "Rate: "; rate
'and that is the result of dithering
r2 = (1 - rate)
'the dithered colour
tr = red(sel) * rate + red(sel2) * r2
tg = green(sel) * rate + green(sel2) * r2
tb = blue(sel) * rate + blue(sel2) * r2
dr = tr - r(m)
dg = tg - g(m)
db = tb - b(m)
'the distance of the dithered colour
td = SQR(dr ^ 2 + dg ^ 2 + db ^ 2)
PRINT "Dithered", tr, tg, tb, td
NEXT m